﻿using System;
using System.Collections.Generic;
using System.Threading;
using Store.WP7.Data.WebStore;
using Store.WP7.Framework.Services;

namespace Store.WP7.Data
{
    public class StoreService : ServiceBase
    {
        #region Customer

        public void LoadCustomerAsync(int customerId, Action<ServiceResult<Customer>> callback)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
            {
                ServiceResult<Customer> serviceResult = new ServiceResult<Customer>();

                try
                {
                    _storeServiceClient.BeginGetCustomer(customerId, asyncResult =>
                    {
                        try {
                            var customer = _storeServiceClient.EndGetCustomer(asyncResult);
                            serviceResult.Result = customer;
                            callback(serviceResult);
                        }
                        catch (Exception xcp) {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }

                    }, state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            }));
        }

        public void AddCustomerAddressAsync(int customerId, Address address, Action<ServiceResult> callback)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
            {
                ServiceResult serviceResult = new ServiceResult();

                try
                {
                    _storeServiceClient.BeginAddCustomerAddress(customerId, address, asyncResult =>
                    {
                        try
                        {
                            _storeServiceClient.EndAddCustomerAddress(asyncResult);
                            callback(serviceResult);
                        }
                        catch (Exception xcp)
                        {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }

                    }, state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            }));
        }
        #endregion
        
        #region Products
        
        public void LoadProductsAsync(Action<ServiceResult<List<Product>>> callback)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
            {
                ServiceResult<List<Product>> serviceResult = new ServiceResult<List<Product>>();
                try
                {
                    _storeServiceClient.BeginGetProducts(asyncResult =>
                    {
                        try
                        {
                            var products = _storeServiceClient.EndGetProducts(asyncResult);
                            serviceResult.Result = products;
                            callback(serviceResult);
                        }
                        catch (Exception xcp)
                        {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }

                    }, state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            }));
        }

        public void LoadHomeProductsAsync(Action<ServiceResult<List<Product>>> callback)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
            {
                ServiceResult<List<Product>> serviceResult = new ServiceResult<List<Product>>();
                try
                {
                    _storeServiceClient.BeginGetHomeProducts(5, asyncResult =>
                    {
                        try
                        {
                            var products = _storeServiceClient.EndGetHomeProducts(asyncResult);
                            serviceResult.Result = products;
                            callback(serviceResult);
                        }
                        catch (Exception xcp)
                        {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }

                    }, state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            }));
        }

        public void LoadProductAsync(int productId, Action<ServiceResult<Product>> callback)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
            {
                ServiceResult<Product> serviceResult = new ServiceResult<Product>();

                try
                {
                    _storeServiceClient.BeginGetProduct(productId, asyncResult =>
                    {

                        try
                        {
                            var product = _storeServiceClient.EndGetProduct(asyncResult);
                            serviceResult.Result = product;
                            callback(serviceResult);
                        }
                        catch (Exception xcp)
                        {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }

                    }, state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            }));
        }
        #endregion

        #region Orders

        public void LoadOrdersAsync(int customerId, Action<ServiceResult<List<Order>>> callback)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
            {
                ServiceResult<List<Order>> serviceResult = new ServiceResult<List<Order>>();
                try
                {
                    _storeServiceClient.BeginGetOrders(customerId, new AsyncCallback(asyncResult =>
                    {

                        try
                        {
                            var customerCommands = _storeServiceClient.EndGetOrders(asyncResult);
                            serviceResult.Result = customerCommands;
                            callback(serviceResult);
                        }
                        catch (Exception xcp)
                        {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }

                    }), state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            }));
        }

        public void LoadHomeOrdersAsync(int customerId, Action<ServiceResult<List<Order>>> callback)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
            {
                ServiceResult<List<Order>> serviceResult = new ServiceResult<List<Order>>();
                try
                {
                    _storeServiceClient.BeginGetHomeOrders(customerId, 5, new AsyncCallback(asyncResult =>
                    {

                        try
                        {
                            var customerCommands = _storeServiceClient.EndGetHomeOrders(asyncResult);
                            serviceResult.Result = customerCommands;
                            callback(serviceResult);
                        }
                        catch (Exception xcp)
                        {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }

                    }), state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            }));
        }

        public void LoadOrderAsync(int orderId, Action<ServiceResult<Order>> callback)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
            {
                ServiceResult<Order> serviceResult = new ServiceResult<Order>();
                try
                {
                    _storeServiceClient.BeginGetOrder(orderId, new AsyncCallback(asyncResult =>
                    {

                        try
                        {
                            var command = _storeServiceClient.EndGetOrder(asyncResult);
                            serviceResult.Result = command;
                            callback(serviceResult);
                        }
                        catch (Exception xcp)
                        {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }

                    }), state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            }));
        }

        public void SubmitOrderAsync(Order order, Action<ServiceResult> callback)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
            {
                ServiceResult serviceResult = new ServiceResult();
                try
                {
                    _storeServiceClient.BeginSubmitOrder(order, new AsyncCallback(asyncResult =>
                    {
                        try
                        {
                            _storeServiceClient.EndSubmitOrder(asyncResult);
                            callback(serviceResult);
                        }
                        catch (Exception xcp)
                        {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }
                    }), state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            }));
        }

        public void UpdateOrderAsync(Order order, Action<ServiceResult> callback)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
            {
                ServiceResult serviceResult = new ServiceResult();
                try
                {
                    _storeServiceClient.BeginUpdateOrder(order, new AsyncCallback(asyncResult =>
                    {
                        try
                        {
                            _storeServiceClient.EndUpdateOrder(asyncResult);
                            callback(serviceResult);
                        }
                        catch (Exception xcp)
                        {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }
                    }), state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            }));
        }

        public void GetOrderStateAsync(int orderId, Action<ServiceResult<int>> callback)
        {
            ThreadPool.QueueUserWorkItem(state =>
            {
                ServiceResult<int> serviceResult = new ServiceResult<int>();

                try
                {
                    _storeServiceClient.BeginGetOrderState(orderId, asyncResult =>
                    {
                        try
                        {
                            int orderState = _storeServiceClient.EndGetOrderState(asyncResult);
                            serviceResult.Result = orderState;
                            callback(serviceResult);
                        }
                        catch (Exception xcp)
                        {
                            serviceResult.Error = xcp;
                            callback(serviceResult);
                        }
                    }, state);
                }
                catch (Exception e)
                {
                    serviceResult.Error = e;
                    callback(serviceResult);
                }
            });
        }

        #endregion
    }
}
